package com.qsw.qswcommonlib.util;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import java.text.DecimalFormat;

/**
 * 通用工具
 */

public class CommonUtil {

    private static boolean mDebug = true;

    private static final Handler mHandler = new Handler(Looper.getMainLooper());

    private static Toast mToast;

    private static Toast mDebugToast;

    private static OnLogListener mOnLogListener;

    private CommonUtil() {
    }

    /**
     * 设置日志输出回调
     *
     * @param onLogListener 日志输出回调
     */
    public static void setOnLogListener(OnLogListener onLogListener) {
        mOnLogListener = onLogListener;
    }

    /**
     * 设置是否为调试模式， 非调试模式下部分调试代码不执行
     *
     * @param debug true：调试模式；false：非调试模式
     */
    public static void setDebug(boolean debug) {
        mDebug = debug;
    }

    /**
     * 判断当前是否为调试模式
     *
     * @return true：调试模式；false：非调试模式
     */
    public static boolean isDebug() {
        return mDebug;
    }

    /**
     * 运行在主线程
     *
     * @param runnable 要运行的代码
     */
    public static void runOnUIThread(Runnable runnable) {
        mHandler.post(runnable);
    }

    /**
     * 在任意位置弹出Toast，多次调用Toast会依次弹出
     *
     * @param context 环境
     * @param resId   Toast内容
     */
    public static void showToast(Context context, int resId) {
        showToast(context, context.getString(resId));
    }

    /**
     * 在任意位置弹出Toast，多次调用Toast会依次弹出
     *
     * @param context 环境
     * @param msg     Toast内容
     */
    public static void showToast(final Context context, final String msg) {
        runOnUIThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
            }
        });
    }

    /**
     * 在任意位置弹出Toast，多次调用会弹出最后一个Toast
     *
     * @param context 环境
     * @param resId   Toast内容
     */
    public static void showSingleToast(Context context, int resId) {
        showSingleToast(context, context.getString(resId));
    }

    /**
     * 在任意位置弹出Toast，多次调用会弹出最后一个Toast
     *
     * @param context 环境
     * @param msg     Toast内容
     */
    public static void showSingleToast(final Context context, final String msg) {
        runOnUIThread(new Runnable() {
            @Override
            public void run() {
                if (mToast != null) {
                    mToast.cancel();
                }
                mToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
                mToast.show();
            }
        });
    }

    /**
     * 在任意位置弹出测试版Toast，多次调用Toast会依次弹出
     * 非调试模式不会弹出
     *
     * @param context 环境
     * @param resId   Toast内容
     */
    public static void showDebugToast(Context context, int resId) {
        if (!mDebug) {
            return;
        }
        showDebugToast(context, context.getString(resId));
    }

    /**
     * 在任意位置弹出测试版Toast，多次调用Toast会依次弹出
     * 非调试模式不会弹出
     *
     * @param context 环境
     * @param msg     Toast内容
     */
    public static void showDebugToast(final Context context, final String msg) {
        if (!mDebug) {
            return;
        }
        runOnUIThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
            }
        });
    }

    /**
     * 在任意位置弹出测试版Toast，多次调用会弹出最后一个Toast
     * 非调试模式不会弹出
     *
     * @param context 环境
     * @param resId   Toast内容
     */
    public static void showDebugSingleToast(Context context, int resId) {
        if (!mDebug) {
            return;
        }
        showDebugSingleToast(context, context.getString(resId));
    }

    /**
     * 在任意位置弹出测试版Toast，多次调用会弹出最后一个Toast
     * 非调试模式不会弹出
     *
     * @param context 环境
     * @param msg     Toast内容
     */
    public static void showDebugSingleToast(final Context context, final String msg) {
        if (!mDebug) {
            return;
        }
        runOnUIThread(new Runnable() {
            @Override
            public void run() {
                if (mDebugToast != null) {
                    mDebugToast.cancel();
                }
                mDebugToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
                mDebugToast.show();
            }
        });
    }

    /**
     * 打印最低级别日志
     * 非调试模式不会打印
     *
     * @param tag log的TAG
     * @param msg log信息
     */
    public static void LOGV(String tag, String msg) {
        if (mDebug) {
            Log.v(tag, msg);
            if (mOnLogListener != null) {
                mOnLogListener.onLogV(tag, msg);
            }
        }
    }

    /**
     * 打印调试日志
     * 非调试模式不会打印
     *
     * @param tag log的TAG
     * @param msg log信息
     */
    public static void LOGD(String tag, String msg) {
        if (mDebug) {
            Log.d(tag, msg);
            if (mOnLogListener != null) {
                mOnLogListener.onLogD(tag, msg);
            }
        }
    }

    /**
     * 打印调试日志
     * 非调试模式不会打印，也不会拼接字符串
     *
     * @param tag    log的TAG
     * @param msg1   log信息描述1
     * @param value1 log信息值1
     */
    public static void LOGD(String tag, String msg1, double value1) {
        if (mDebug) {
            StringBuilder sb = new StringBuilder();
            sb.append(msg1);
            sb.append(value1);
            Log.d(tag, sb.toString());
            if (mOnLogListener != null) {
                mOnLogListener.onLogD(tag, sb.toString());
            }
        }
    }

    /**
     * 打印调试日志
     * 非调试模式不会打印，也不会拼接字符串
     *
     * @param tag    log的TAG
     * @param msg1   log信息描述1
     * @param value1 log信息值1
     * @param msg2   log信息描述2
     * @param value2 log信息值2
     */
    public static void LOGD(String tag, String msg1, double value1, String msg2, double value2) {
        if (mDebug) {
            StringBuilder sb = new StringBuilder();
            sb.append(msg1);
            sb.append(value1);
            sb.append(msg2);
            sb.append(value2);
            Log.d(tag, sb.toString());
            if (mOnLogListener != null) {
                mOnLogListener.onLogD(tag, sb.toString());
            }
        }
    }

    /**
     * 打印调试日志
     * 非调试模式不会打印，也不会拼接字符串
     *
     * @param tag    log的TAG
     * @param msg1   log信息描述1
     * @param value1 log信息值1
     * @param msg2   log信息描述2
     * @param value2 log信息值2
     * @param msg3   log信息描述3
     * @param value3 log信息值3
     */
    public static void LOGD(String tag, String msg1, double value1, String msg2, double value2, String msg3, double value3) {
        if (mDebug) {
            StringBuilder sb = new StringBuilder();
            sb.append(msg1);
            sb.append(value1);
            sb.append(msg2);
            sb.append(value2);
            sb.append(msg3);
            sb.append(value3);
            Log.d(tag, sb.toString());
            if (mOnLogListener != null) {
                mOnLogListener.onLogD(tag, sb.toString());
            }
        }
    }

    /**
     * 打印调试日志
     * 非调试模式不会打印，也不会拼接字符串
     *
     * @param tag    log的TAG
     * @param msg1   log信息描述1
     * @param value1 log信息值1
     * @param msg2   log信息描述2
     * @param value2 log信息值2
     * @param msg3   log信息描述3
     * @param value3 log信息值3
     * @param msg4   log信息描述4
     * @param value4 log信息值4
     */
    public static void LOGD(String tag, String msg1, double value1, String msg2, double value2, String msg3, double value3, String msg4, double value4) {
        if (mDebug) {
            StringBuilder sb = new StringBuilder();
            sb.append(msg1);
            sb.append(value1);
            sb.append(msg2);
            sb.append(value2);
            sb.append(msg3);
            sb.append(value3);
            sb.append(msg4);
            sb.append(value4);
            Log.d(tag, sb.toString());
            if (mOnLogListener != null) {
                mOnLogListener.onLogD(tag, sb.toString());
            }
        }
    }

    /**
     * 打印调试日志
     * 非调试模式不会打印，也不会拼接字符串
     *
     * @param tag    log的TAG
     * @param msg1   log信息描述1
     * @param value1 log信息值1
     */
    public static void LOGD(String tag, String msg1, long value1) {
        if (mDebug) {
            StringBuilder sb = new StringBuilder();
            sb.append(msg1);
            sb.append(value1);
            Log.d(tag, sb.toString());
            if (mOnLogListener != null) {
                mOnLogListener.onLogD(tag, sb.toString());
            }
        }
    }

    /**
     * 打印调试日志
     * 非调试模式不会打印，也不会拼接字符串
     *
     * @param tag    log的TAG
     * @param msg1   log信息描述1
     * @param value1 log信息值1
     * @param msg2   log信息描述2
     * @param value2 log信息值2
     */
    public static void LOGD(String tag, String msg1, long value1, String msg2, long value2) {
        if (mDebug) {
            StringBuilder sb = new StringBuilder();
            sb.append(msg1);
            sb.append(value1);
            sb.append(msg2);
            sb.append(value2);
            Log.d(tag, sb.toString());
            if (mOnLogListener != null) {
                mOnLogListener.onLogD(tag, sb.toString());
            }
        }
    }

    /**
     * 打印调试日志
     * 非调试模式不会打印，也不会拼接字符串
     *
     * @param tag    log的TAG
     * @param msg1   log信息描述1
     * @param value1 log信息值1
     * @param msg2   log信息描述2
     * @param value2 log信息值2
     * @param msg3   log信息描述3
     * @param value3 log信息值3
     */
    public static void LOGD(String tag, String msg1, long value1, String msg2, long value2, String msg3, long value3) {
        if (mDebug) {
            StringBuilder sb = new StringBuilder();
            sb.append(msg1);
            sb.append(value1);
            sb.append(msg2);
            sb.append(value2);
            sb.append(msg3);
            sb.append(value3);
            Log.d(tag, sb.toString());
            if (mOnLogListener != null) {
                mOnLogListener.onLogD(tag, sb.toString());
            }
        }
    }

    /**
     * 打印调试日志
     * 非调试模式不会打印，也不会拼接字符串
     *
     * @param tag    log的TAG
     * @param msg1   log信息描述1
     * @param value1 log信息值1
     * @param msg2   log信息描述2
     * @param value2 log信息值2
     * @param msg3   log信息描述3
     * @param value3 log信息值3
     * @param msg4   log信息描述4
     * @param value4 log信息值4
     */
    public static void LOGD(String tag, String msg1, long value1, String msg2, long value2, String msg3, long value3, String msg4, long value4) {
        if (mDebug) {
            StringBuilder sb = new StringBuilder();
            sb.append(msg1);
            sb.append(value1);
            sb.append(msg2);
            sb.append(value2);
            sb.append(msg3);
            sb.append(value3);
            sb.append(msg4);
            sb.append(value4);
            Log.d(tag, sb.toString());
            if (mOnLogListener != null) {
                mOnLogListener.onLogD(tag, sb.toString());
            }
        }
    }

    /**
     * 打印信息日志
     *
     * @param tag log的TAG
     * @param msg log信息
     */
    public static void LOGI(String tag, String msg) {
        Log.i(tag, msg);
        if (mOnLogListener != null) {
            mOnLogListener.onLogI(tag, msg);
        }
    }

    /**
     * 打印警告日志
     *
     * @param tag log的TAG
     * @param msg log信息
     */
    public static void LOGW(String tag, String msg) {
        Log.w(tag, msg);
        if (mOnLogListener != null) {
            mOnLogListener.onLogW(tag, msg);
        }
    }

    /**
     * 打印错误日志
     *
     * @param tag log的TAG
     * @param msg log信息
     */
    public static void LOGE(String tag, String msg) {
        Log.e(tag, msg);
        if (mOnLogListener != null) {
            mOnLogListener.onLogE(tag, msg);
        }
    }

    /**
     * 获取apk当前版本号
     *
     * @param context 环境
     * @return 当前版本号，若获取失败则返回-1（包名异常）
     */
    public static int getVersionCode(Context context) throws PackageManager.NameNotFoundException {
        return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
    }

    /**
     * 获取apk当前版本名
     *
     * @param context 环境
     * @return 当前版本名，若获取失败则返回null（包名异常）
     */
    public static String getVersionName(Context context) throws PackageManager.NameNotFoundException {
        return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
    }

    /**
     * 获取百分比
     *
     * @param curr  当前数值
     * @param total 总数值
     * @return 当前数值相对总数值所占的百分数
     */
    public static int getPercent(int curr, int total) {
        return (int) (100L * curr / total);
    }

    /**
     * b（字节）转换为M（兆）
     *
     * @param b 字节
     * @return 转换结果
     */
    public static String b2M(int b) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00");// 构造方法的字符格式这里如果小数不足2位,会以0补足.
        return decimalFormat.format(1.0 * b / 1024 / 1024);// format 返回的是字符串
    }

    /**
     * 当调用日志输出时的回调
     */
    public interface OnLogListener {
        void onLogV(String tag, String msg);

        void onLogD(String tag, String msg);

        void onLogI(String tag, String msg);

        void onLogW(String tag, String msg);

        void onLogE(String tag, String msg);
    }

    /**
     * 当调用日志输出时的回调
     */
    public abstract class OnLogListenerBase implements OnLogListener {
        @Override
        public void onLogV(String tag, String msg) {
        }

        @Override
        public void onLogD(String tag, String msg) {
        }

        @Override
        public void onLogI(String tag, String msg) {
        }

        @Override
        public void onLogW(String tag, String msg) {
        }

        @Override
        public abstract void onLogE(String tag, String msg);
    }
}

